#![allow(dead_code)]

pub const VERTEX_INPUT_POSITION: u32 = 0;
pub const TEX_COORD_INPUT_POSITION: u32 = 2;

pub const SIMPLE_TEX_VERTEX_SHADER_SRC: &[u8] = b"\
#version 330 core \n
layout (location = 0) in vec2 vPosition; \n
layout (location = 2) in vec2 vTexCoord; \n
out vec2 texCoord; \n
void main() { \n
    gl_Position = vec4(vPosition, 0.0, 1.0); \n
    texCoord = vTexCoord; \n
} \n\0";

pub const GEO_VERTEX_SHADER_SRC: &[u8] = b"#version 330 core \n
layout (location = 0) in vec2 vPosition;\n
layout (location = 1) in vec4 vColor; \n
out vec4 fColor; \n
uniform mat4 proj;
uniform mat4 trans; \n
void main() {\n
    gl_Position = proj * trans * vec4(vPosition, 0.0, 1.0);\n
    fColor = vColor; \n
}\0";

pub const GEO_FRAGMENT_SHADER_SRC: &[u8] = b"#version 330 core \n
in vec4 fColor; \n
out vec4 FragColor;\n
void main() {\n
    FragColor = fColor;\n
}\0";

pub const TEX_VERTEX_SHADER_SRC: &[u8] = b"\
#version 330 core \n
layout (location = 0) in vec2 vPosition; \n
layout (location = 2) in vec2 vTexCoord; \n
out vec2 texCoord; \n
uniform mat4 proj; \n
uniform mat4 trans; \n
void main() { \n
    gl_Position = proj * trans * vec4(vPosition, 0.0, 1.0);
    texCoord = vTexCoord;
} \0";

pub const TEX_FRAGMENT_SHADER_SRC: &[u8] = b"\
#version 330 core \n
in vec2 texCoord; \n
out vec4 FragColor;\n
uniform sampler2D tex; \n
uniform int modes; \n
void main() {\n
    vec4 texColor = texture(tex, texCoord); \n\
    if (modes == 1) { \n\
        //float gray = 0.299 * texColor.r + 0.587 * texColor.g + 0.114 * texColor.b; \n\
        float gray = (texColor.r + texColor.g + texColor.b) / 3.0; \n
        texColor = vec4(gray, gray, gray, 1.0); \n
    } else if (modes == 2) {\n\
        texColor = vec4(vec3(1.0 - texColor), 1.0);
    }
    FragColor = texColor; \n
}\0";

use std::ffi::{CString, CStr, FromBytesWithNulError};
use std::ptr;
use std::os::raw::c_char;

pub fn c_str(rstr: &str) -> *const c_char {
    CString::new(rstr).unwrap().into_raw()
}

pub fn new_shader_module(shader_type: u32, src: &[u8]) -> Result<u32, FromBytesWithNulError> {
    unsafe {
        let handle = gl::CreateShader(shader_type);
        let src = CStr::from_bytes_with_nul(src)?;
        gl::ShaderSource(handle, 1, &src.as_ptr(), ptr::null());
        gl::CompileShader(handle);

        let mut success = 0;
        let mut buffer = [0i8; 512];
        gl::GetShaderiv(handle, gl::COMPILE_STATUS, &mut success);
        if success == 0 {
            gl::GetShaderInfoLog(handle, 512, ptr::null_mut(), buffer.as_mut_ptr());
            let str = CStr::from_ptr(buffer.as_ptr());
            match shader_type {
                gl::VERTEX_SHADER => println!("VERTEX_SHADER_COMPILE: \n ---------------- \n{}", str.to_str().unwrap()),
                gl::FRAGMENT_SHADER => println!("FRAGMENT_SHADER_COMPILE: \n ---------------- \n{}", str.to_str().unwrap()),
                _ => ()
            }
        }
        Ok(handle)
    }
}